package edu.umassd.raddacl.dataset;

import java.util.ArrayList;
import java.util.Iterator;

import edu.umassd.raddacl.Observation;

/**
 * A class that represents an observation in a default data set.
 * 
 * @author Dan Avila
 * 
 */
class DefaultObservation implements Observation
{
	private static final ArrayList<DefaultObservation> CACHE = new ArrayList<>();
	private int row;
	private DefaultDataSet dataset;

	private DefaultObservation()
	{

	}

	@Override
	public Iterator<Double> iterator()
	{
		return new AttributeIterator();
	}

	@Override
	public Double get(int attribute)
	{
		return Double.valueOf(dataset.get(row, attribute));
	}

	@Override
	public int size()
	{
		return dataset.getNumberOfAttributes();
	}

	@Override
	public String toString()
	{
		StringBuilder builder = new StringBuilder();

		boolean first = true;

		for (Double attr : this)
		{
			if (!first)
			{
				builder.append(",");
			}

			builder.append(attr);
			first = false;
		}

		return builder.toString();
	}

	private class AttributeIterator implements Iterator<Double>
	{
		private int currentAttribute = 0;

		@Override
		public boolean hasNext()
		{
			return currentAttribute < dataset.getNumberOfAttributes();
		}

		@Override
		public Double next()
		{
			try
			{
				return get(currentAttribute);
			}
			finally
			{
				currentAttribute++;
			}
		}

		@Override
		public void remove()
		{
			throw new UnsupportedOperationException(
					"Data Sets are unmodifiable.");
		}
	}

	static DefaultObservation createNewObservation(int row, DefaultDataSet set)
	{
		try
		{
			return CACHE.get(row);
		}
		catch (IndexOutOfBoundsException e)
		{
			DefaultObservation obs = new DefaultObservation();

			obs.dataset = set;
			obs.row = row;

			while (CACHE.size() <= row)
			{
				CACHE.add(null);
			}

			CACHE.set(row, obs);
		}

		return CACHE.get(row);
	}
}
